﻿#pragma once
#ifndef Device_hpp
#define Device_hpp


#include<string>
#include<vector>
#include<stdexcept>
#include<functional>
#include<memory>
#include"./DataTypeDef.hpp"


namespace MMF
{

    /***
     * 基础设备类
     * 这个主要时配置信息
    */
    struct MMFDevice
    {
        std::vector<MMFDataType> mInType;       ///< 输入数据类型
        std::vector<MMFDataType> mOutType;      ///< 输出数据类型
        std::string mName;                      ///< 设备名,最长256字节
        std::string mLibrayFile;                ///< 动态库名,最长256字节
        std::string mCreateFuncName;            ///< 实例函数得名字,最长256字节
        std::string mExtendInfo;                ///< 额外得扩展信息,最长256字节,这个东西最好使用kv(k1=v1,k2=v2)
        bool mIsSingle;                         ///< 设备只能创建一个实例
    };


    /***
     * 异步时的异常
    */
    class MMFAsyncError:std::logic_error
    {
        int64_t mErr;
        std::string mMassage;

    public:

        MMFAsyncError(int64_t err, const std::string& msg)
            : mErr(err)
            , mMassage(msg)
            , std::logic_error(mMassage.c_str())
        {}

        int64_t Code() {return mErr;}
        const char* Message() {return mMassage.c_str();}
        bool OK() {return mErr == 0;};
    };


    /***
     * 异步回调函数
    */
    using MMFAsyncCallback = std::function<void(const MMFAsyncError&)>;
    

    /***
     * 设备接口
    */
    class MMFDeviceInterface
    {
    
    public:

        //虚析构
        ~MMFDeviceInterface(){};

        //探测函数
        virtual bool Probe() = 0; 

        //设备已经准备好
        //当一个设备初始化完成后就应该时在ready状态了
        virtual bool Ready() = 0;      

        //开始函数
        virtual void Start() = 0;

        //运行函数
        virtual void Run() = 0;

        //停止函数
        virtual void Abort() = 0;

        //暂停函数
        virtual void Pause() = 0;

        //回复函数
        virtual void Resume() = 0;

        //获取输入端口数
        virtual uint32_t InPortNum() = 0;

        //数去输出端口数量
        virtual uint32_t OutPortNum() = 0;

        //获取输入端口数据类型
        virtual MMFDataType GetInDataType(uint32_t portIndex) = 0;

        //获取输出端口数据类型
        virtual MMFDataType GetOutDataType(uint32_t portIndex) = 0;

        //写入数据
        virtual uint64_t Write(const std::vector<MMFDataBuffer>& buffers) = 0;

        //读取数据
        virtual uint64_t Read(const std::vector<MMFDataBuffer>& buffers) = 0;

        //异步写入
        virtual bool AsyncWrite(const std::vector<MMFDataBuffer>& buffers, const MMFAsyncCallback& callback) = 0;

        //异步读取
        virtual bool AsyncRead(const std::vector<MMFDataBuffer>& buffers, const MMFAsyncCallback& callback) = 0;

        //设置参数
        virtual void Config(const MMFDeviceCfgBase& cfg) = 0;

        //获取参数
        virtual const MMFDeviceCfgBase& Config() = 0;

        //设置上下文
        virtual void Ctx(const MMFCtx& ctx) = 0;

        //获取上下文
        virtual MMFCtx Ctx() = 0;
    };


    /***
     * 创建函数类型
     * 用于转换设备动态库中得函数
     * 这里被设计为函数指针
    */
    using DeviceCreateFunc = MMFDeviceInterface* (*)(const MMFDeviceCfgBase& cfg);
}


#endif